package com.woniu.handler;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.woniu.entity.UserInfo;
import com.woniu.utils.ResData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import static com.woniu.constant.Constant.Security.JWT_SECRET_KEY;

@Component
public class LoginSuccessHandler implements ServerAuthenticationSuccessHandler {

    @Autowired
    ReactiveStringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
        UserInfo userInfo = (UserInfo) authentication.getPrincipal();

        Map<String, Object> map = new HashMap<>();
        map.put("id", userInfo.getId());
        map.put("username", userInfo.getUsername());
        map.put("authorities", userInfo.getAuthorities());

        String authToken = JWTUtil.createToken(map, JWT_SECRET_KEY.getBytes());

        return redisTemplate.opsForValue().set("JWToken:" + authToken, authToken, Duration.ofMinutes(30))
                .then(Mono.defer(() -> {
                    response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                    return response.writeWith(
                            Mono.just(response.bufferFactory().wrap(
                                    JSONUtil.toJsonStr(
                                            ResData.successLogin(authToken, "登录成功")
                                    ).getBytes(StandardCharsets.UTF_8))
                            )
                    );
                }));
    }
}
